package com.xiaofeng.pochi.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaofeng.pochi.common.Page;
import com.xiaofeng.pochi.enums.StateEnums;
import com.xiaofeng.pochi.exception.PochiException;
import com.xiaofeng.pochi.mapper.*;
import com.xiaofeng.pochi.pojo.*;
import com.xiaofeng.pochi.pojo.dto.ShopCouponDto;
import com.xiaofeng.pochi.pojo.vo.SysUserVo;
import com.xiaofeng.pochi.service.ShopCouponService;
import com.xiaofeng.pochi.service.ShopPackService;
import com.xiaofeng.pochi.utils.IdWorker;
import com.xiaofeng.pochi.utils.ShiroUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA
 *
 * @Author: chc
 * @Date: 2022/08/18/23:29
 * @Description:
 */
@Service
public class ShopCouponServiceImpl extends ServiceImpl<ShopCouponMapper, ShopCoupon> implements ShopCouponService {

    @Autowired
    private IdWorker IdWorker;
    @Autowired
    private ShopCouponMapper shopCouponMapper;

    @Autowired
    private ShopProductMapper shopProductMapper;
    @Autowired
    private ShopCouponProductMapper shopCouponProductMapper;
    @Autowired
    private ShopCouponCategoryMapper shopCouponCategoryMapper;

    @Autowired
    private ShopCouponHistoryMapper shopCouponHistoryMapper;

    @Autowired
    private ShopUserStatisticMapper shopUserStatisticMapper;


    @Override
    public void save(ShopCouponDto shopCouponDto) {
        long couponId = IdWorker.nextId();
        //复制属性
        ShopCoupon shopCoupon = new ShopCoupon();
        BeanUtils.copyProperties(shopCouponDto,shopCoupon);
        // 设置默认值
        LoginUser loginUser = ShiroUtils.getLoginUser();
        shopCoupon.setId(couponId);
        shopCoupon.setCreateBy(loginUser.getUsername());
        shopCoupon.setUpdateBy(loginUser.getUsername());
        shopCoupon.setRestCount(shopCoupon.getPublishCount());
        shopCouponMapper.save(shopCoupon);
        // 如果有分类，添加优惠券-分类关联
        if (StateEnums.CATEGORY.getCode().equals(shopCoupon.getCouponType())) {
            List<ShopCouponCategory> couponCategoryList = shopCouponDto.getCategoryList().stream().map(e -> new ShopCouponCategory(couponId, e.getId())).collect(Collectors.toList());
            shopCouponCategoryMapper.saveBatch(couponCategoryList);
        }
        // 如果有商品，添加优惠券-商品关联
        if (StateEnums.PRODUCT.getCode().equals(shopCoupon.getCouponType())) {
            List<ShopCouponProduct> couponProductList = shopCouponDto.getProductList().stream().map(e -> new ShopCouponProduct(couponId, e.getId())).collect(Collectors.toList());
            shopCouponProductMapper.saveBatch(couponProductList);
        }
    }

    @Override
    public void delete(Long id) {
        QueryWrapper<ShopCoupon> query = new QueryWrapper<>();
        query.lambda().eq(ShopCoupon::getId,id);
        ShopCoupon shopCoupon  = new ShopCoupon();
        shopCoupon.setDeleted(1);
        shopCouponMapper.update(shopCoupon,query);
    }

    @Override
    public void down(Long id) {
        shopCouponMapper.down(id);
    }

    @Override
    public Page<ShopCoupon> getByPage(Page<ShopCoupon> page) {
        List<ShopCoupon> list = shopCouponMapper.getByPage(page);
        Integer totalCount = shopCouponMapper.countByPage(page);
        page.setList(list);
        page.setTotalCount(totalCount);
        return page;
    }

    @Override
    public List<ShopCoupon> getProductCoupon(Long productId) {
        // 查询商品信息
        ShopProduct product = shopProductMapper.getInfoById(productId);
        // 查询全场通用优惠券
        List<ShopCoupon> bothList = shopCouponMapper.getBothCoupon();
        // 查询该商品所在分类的优惠券
        List<ShopCoupon> categoryCouponList = shopCouponMapper.getByCategoryId(product.getCategoryId());
        // 查询该商品的优惠券
        List<ShopCoupon> productCouponList = shopCouponMapper.getByProductId(productId);
        bothList.addAll(categoryCouponList);
        bothList.addAll(productCouponList);
        if (!CollectionUtils.isEmpty(bothList)){
            // 根据优惠券id集合和用户账号查询优惠券领取历史，判断优惠券是否已经被领取
            List<Long> couponIds = bothList.stream().map(ShopCoupon::getId).collect(Collectors.toList());
            String username = ShiroUtils.getLoginUser().getUsername();
            List<ShopCouponHistory> historyList = shopCouponHistoryMapper.getByCouponIdsAndUsername(couponIds, username);
            if (!CollectionUtils.isEmpty(historyList)){
                bothList.forEach(c ->{
                    ShopCouponHistory history = historyList.stream().filter(h -> h.getCouponId().equals(c.getId())).findFirst().orElse(null);
                    if (history != null){
                        c.setStatus(StateEnums.COUPON_RECEIVED.getCode());
                    }
                });

            }
        }
        return bothList;
    }

    @Override
    public void updateTimeoutCoupon() {
        shopCouponMapper.updateTimeoutCoupon();
    }

    @Override
    public void catchCoupon(ShopCoupon shopCoupon) {
        LoginUser loginUser = ShiroUtils.getLoginUser();
        // 1. 查询优惠券数据，校验剩余数量
        ShopCoupon coupon = shopCouponMapper.get(shopCoupon.getId());
        if (coupon.getRestCount() <= 0) {
            throw new PochiException("优惠券已经领取完毕");
        }
        // 2. 更新领取数量和剩余数量
        coupon.setRestCount(coupon.getRestCount() - 1);
        coupon.setReceiveCount(coupon.getReceiveCount() + 1);
        shopCouponMapper.updateCount(coupon);
        // 3. 在优惠券历史表中插入一条领取记录，状态为未使用
        ShopCouponHistory shopCouponHistory = new ShopCouponHistory();
        shopCouponHistory.setCouponId(coupon.getId());
        shopCouponHistory.setCreateBy(loginUser.getUsername());
        shopCouponHistory.setAmount(coupon.getAmount());
        shopCouponHistory.setMinPoint(coupon.getMinPoint());
        shopCouponHistoryMapper.save(shopCouponHistory);
        // 4. 在用户统计表中将优惠券数量+1
        ShopUserStatistic statistic = shopUserStatisticMapper.getByUserId(loginUser.getId());
        statistic.setCouponCount(statistic.getCouponCount() + 1);
        shopUserStatisticMapper.update(statistic);
    }

    @Override
    public ShopCoupon get(Long id) {
        return shopCouponMapper.get(id);
    }

    @Override
    public List<ShopCouponHistory> getHistoryList(Long id) {
        return shopCouponHistoryMapper.getByCouponId(id);
    }
}
